import request from "@/uni_modules/uniapp-kantboot/libs/request";
import rsa from "@/uni_modules/uniapp-kantboot/libs/rsa";
import cryptoJs from "@/uni_modules/uniapp-kantboot/libs/cryptoJs";

/**
 * 设置服务端公钥
 */
let setServerPublicKey = function (publicKey) {
    uni.setStorageSync("serverPublicKey", publicKey);
}

/**
 * 获取服务端公钥
 */
let getServerPublicKey = () => {
    return uni.getStorageSync("serverPublicKey");
}

/**
 * 获取请求地址
 */
let getRequestUrl = function (options) {
    // 获取根地址
    let rootAddress = request.getRootAddress();
    // 如果是/结尾，则去掉结尾
    if (rootAddress.endsWith("/")) {
        rootAddress = rootAddress.substring(0, rootAddress.length - 1);
    }

    // 获取uri
    let uri = options.uri;
    // 如果uri是/开头，则去掉开头
    if (uri.startsWith("/")) {
        uri = options.uri.substring(1);
    }

    return rootAddress + "/security/simpleForward/" + uri;
}

/**
 * 生成客户端密钥
 */
let generateClientKey = function () {
    let arr = [
        "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
        "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
        "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
    ];
    let clientKey = "";
    for (let i = 0; i < 32; i++) {
        clientKey += arr[Math.floor(Math.random() * arr.length)];
    }
    uni.setStorageSync("clientKey", clientKey);
    return clientKey;
}

/**
 * 获取客户端密钥
 */
let getClientKey = function () {
    return uni.getStorageSync("clientKey");
}


/**
 * 生成content
 * @param options
 */
let getContent = function (options) {
    // 获取服务端传来的公钥
    let serverPublicKey = getServerPublicKey();
    // 将options.data加密
    let encryptStr = rsa.encrypt(serverPublicKey, JSON.stringify(options.data));
    let clientKey = getClientKey();
    if (!clientKey) {
        clientKey = generateClientKey();
    }
    // 获取加密后的clientKey
    let clientKeyRsa = rsa.encrypt(serverPublicKey, clientKey);
    // 分为三个.分割，第一个是后端生成的公钥，第二个前端加密后的请求体，第三个是客户端生成的公钥
    return serverPublicKey + "." + encryptStr + "." + clientKeyRsa;
}


let requestSecurity = async (options) => {

    setTimeout(async () => {

        if (!options.data) {
            // 给options.data赋值，防止options.data为null
            options.data = {};
        }

        // 获取服务端传来的公钥
        let serverPublicKey = getServerPublicKey();
        if (!serverPublicKey) {

            await new Promise((resolve) => {
                // 向服务端请求公钥
                request.request({
                    uri: "/security/getNewPublicKey",
                    stateSuccess: (res) => {
                        setServerPublicKey(res.data);
                        resolve();
                    }
                });
            });
        }

        uni.request({
            url: getRequestUrl(options),
            method: "POST",
            header: {
                token: request.getToken(),
                languageCode: request.getLanguageCode(),
                ...options.header
            },
            data: {
                content: getContent(options)
            },
            success: (res) => {
                let data = res.data;
                if (!data.success && options?.stateFail) {
                    // 如果安全保障过期，则重新请求安全保障
                    if (data.stateCode === "securityExpire") {
                        console.log("安全保障过期，重新请求安全保障");
                        // 清空服务端公钥
                        setServerPublicKey(null);
                        // 清空前端生成的密钥
                        uni.setStorageSync("clientKey", null);
                        requestSecurity(options);
                        return;
                    }

                    // 如果服务端公钥错误，则重新请求服务端公钥
                    if (data.stateCode === "publicKeyError") {
                        console.log("服务端公钥错误，重新请求服务端公钥");
                        // 清空客户端密钥
                        clearKey();
                        // 重新请求服务端公钥
                        requestSecurity(options);
                        return;
                    }

                    // 如果存在安全风险（securityRisk），则完全退出
                    if (data.stateCode === "securityRisk") {
                        console.error("安全风险，请求终止");
                        // 清空服务端公钥
                        setServerPublicKey(null);
                        // 清空前端生成的密钥
                        uni.setStorageSync("clientKey", null);
                        // 删除token
                        uni.removeStorageSync("token");
                        uni.showToast({
                            title: data.errMsg,
                            icon: "none"
                        });
                        setTimeout(() => {
                            uni.reLaunch({
                                url: "/pages/login/login"
                            });
                        });
                        return;
                    }

                    options?.stateFail(data);
                    return;
                }


                // AES解密data.data
                let decryptData = cryptoJs.decryptData(data.data, getClientKey());
                let json = JSON.parse(decryptData);

                console.log("URI：\n", options.uri, "\n\n",
                    "请求数据：\n", options.data, "\n\n",
                    "原始数据：\n", data, "\n\n",
                    "解密后的数据：\n", JSON.stringify(json)
                );

                //如果是没登录
                if (json.stateCode === "notLogin") {
                    console.log("未登录")
                    //uni提示未登录
                    uni.showToast({
                        title: "未登录",
                        icon: "none"
                    });
                    //跳转登录页
                    uni.navigateTo({
                        url: '/pages/login/login',  // 登录页的路径，根据你的实际情况修改
                    });


                }

                // 如果stateCode为SUCCESS，则调用options.stateSuccess
                if (json.success && options?.stateSuccess) {
                    options?.stateSuccess(json);
                    return;
                }
                if (options?.stateFail) {
                    options?.stateFail(json);
                }

            },
            fail: (res) => {
                if (res.errMsg.startsWith("request:fail ")) {
                    console.error("网络请求失败，请检查网络连接");
                    options?.stateFail({
                        success: false,
                        errMsg: "网络请求失败，请检查网络连接",
                        msgDictCode: "networkError",
                        operationCode: null,
                        state: 3000,
                        stateCode: "networkError"
                    });
                }
            }
        });

    }, 0);

}


let clearKey = function () {
    uni.setStorageSync("serverPublicKey", null);
    uni.setStorageSync("clientKey", null);
}

export default {
    setServerPublicKey,
    getServerPublicKey,
    requestSecurity,
    clearKey
}